﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PCRLE = Pws.Clients.RestLibrary.ECommerce;
using System.IO;

namespace Pws.Clients.RestLibrary.Service
{
	/*
	 * Copyright (C) PWS Distributors Ltd 2011-2013
	 * All rights reserved.
	 * 
	 */

	/// <summary>
	/// An interface to the PWS REST Web Services providing abstraction at the level of Get, Put, Post, and Delete.
	/// All available operations within the Web Services can be actioned via this interface, through combination with
	/// the object definitions within the Pws.Clients.RestLibrary.
	/// 
	/// Instances and operations are thread safe.
	/// </summary>
	public interface IPwsService
	{
		/// <summary>
		/// Get the root service which is the starting point for the PWS REST Web Services.
		/// </summary>
		/// <typeparam name="T">The type of object being received, e.g. a Services_V1 object.</typeparam>
		/// <returns>An object describing the available services.</returns>
		T GetRoot<T>() where T : class;

		/// <summary>
		/// Get an object. This overload can only be used if the service does not require an authentication Token.
		/// </summary>
		/// <param name="service">The absolute URI to the service and object being called. </param>
		/// <returns>Object of type T from service.</returns>
		/// <typeparam name="T">The type of object being received.</typeparam>
		T Get<T>(Uri service) where T : class;

		/// <summary>
		/// Get an object.
		/// </summary>
		/// <param name="service">The absolute URI to the service and object being called. </param>
		/// <param name="tokenV1">A user authentication token which has been provided by the PWS Authentication Token Service.</param>
		/// <returns>Object of type T from service.</returns>
		/// <typeparam name="T">The type of object being received.</typeparam>
		T Get<T>(Uri service, PCRLE.Users.Token_V1 tokenV1) where T : class;

		/// <summary>
		/// Get a list of objects, along with Uri pointing to the previous and next page of results (if applicable).
		/// This overload can only be used if the service does not require an authentication token.
		/// </summary>
		/// <param name="service">The absolute URI to the service and object being called. </param>
		/// <param name="nextPage">A link to the next page of the list. This will be null if there are no more pages of results.</param>
		/// <param name="previousPage">A link to the previous page of the list. This will be null if there are no previous pages of results.</param>
		/// <returns>List of objects of type T from service, representing just one page of results for best performance.</returns>
		/// <typeparam name="T">The type of object being received.</typeparam>
		IList<T> GetList<T>(Uri service, out Uri previousPage, out Uri nextPage) where T : class;

		/// <summary>
		/// Get a list of objects, along with Uri pointing to the previous and next page of results (if applicable).
		/// </summary>
		/// <param name="service">The absolute URI to the service and object being called. </param>
		/// <param name="tokenV1">A user authentication token which has been provided by the PWS Authentication Token Service.</param>
		/// <param name="nextPage">A link to the next page of the list. This will be null if there are no more pages of results.</param>
		/// <param name="previousPage">A link to the previous page of the list. This will be null if there are no previous pages of results.</param>
		/// <returns>List of objects of type T from service, representing just one page of results for best performance.</returns>
		/// <typeparam name="T">The type of object being received.</typeparam>
		IList<T> GetList<T>(Uri service, PCRLE.Users.Token_V1 tokenV1, out Uri previousPage, out Uri nextPage) where T : class;

		/// <summary>
		/// Get a list of objects. This will obtain all pages of results, by repeatedly calling
		/// to get each page in turn. Please use the other overload if supporting pagination, or if the results list is very long.
		/// This overload can only be used if the service does not require an authentication token.
		/// </summary>
		/// <param name="service">The absolute URI to the service and object being called. </param>
		/// <returns>List of objects of type T from service,</returns>
		/// <typeparam name="T">The type of object being received.</typeparam>
		IList<T> GetList<T>(Uri service) where T : class;

		/// <summary>
		/// Get a list of objects. This will obtain all pages of results, by repeatedly calling
		/// to get each page in turn. Please use the other overload if supporting pagination, or if the results list is very long.
		/// </summary>
		/// <param name="service">The absolute URI to the service and object being called. </param>
		/// <param name="tokenV1">A user authentication token which has been provided by the PWS Authentication Token Service.</param>
		/// <returns>List of objects of type T from service,</returns>
		/// <typeparam name="T">The type of object being received.</typeparam>
		IList<T> GetList<T>(Uri service, PCRLE.Users.Token_V1 tokenV1) where T : class;

		/// <summary>
		/// Post a new object, expecting the same object type in return. This overload uses a username and password string.
		/// </summary>
		/// <param name="service">The absolute URI to the service and object being called. </param>
		/// <param name="username">Username for authentication.</param>
		/// <param name="password">Password for authentication.</param>
		/// <param name="sendObject">Object to send.</param>
		/// <returns>Object of type T from service.</returns>
		/// <typeparam name="T">The type of object being sent.</typeparam>
		T Post<T>(Uri service, T sendObject, string username, string password) where T : class;

		/// <summary>
		/// Post a new object, expecting the same object type in return.
		/// </summary>
		/// <param name="service">The absolute URI to the service and object being called. </param>
		/// <param name="sendObject">Object to send.</param>
		/// <param name="tokenV1">A user authentication token which has been provided by the PWS Authentication Token Service.</param>
		/// <returns>Object of type T from service.</returns>
		/// <typeparam name="T">The type of object being sent.</typeparam>
		T Post<T>(Uri service, T sendObject, PCRLE.Users.Token_V1 tokenV1) where T : class;

		/// <summary>
		/// Put (update) an existing object.
		/// </summary>
		/// <param name="service">The absolute URI to the service and object being called. </param>
		/// <param name="sendObject">Object to send.</param>
		/// <param name="tokenV1">A user authentication token which has been provided by the PWS Authentication Token Service.</param>
		/// <returns>Object of type T from service.</returns>
		/// <typeparam name="T">The type of object being sent.</typeparam>
		T Put<T>(Uri service, T sendObject, PCRLE.Users.Token_V1 tokenV1) where T : class;

		/// <summary>
		/// Delete an existing object.
		/// </summary>
		/// <param name="service">The absolute URI to the service and object being called. </param>
		/// <param name="sendObject">Object to send.</param>
		/// <param name="tokenV1">A user authentication token which has been provided by the PWS Authentication Token Service.</param>
		/// <returns>Object of type T from service..</returns>
		/// <typeparam name="T">The type of object being sent.</typeparam>
		void Delete<T>(Uri service, T sendObject, PCRLE.Users.Token_V1 tokenV1) where T : class;

		/// <summary>
		/// Get a binary file, e.g. a PDF.
		/// </summary>
		/// <param name="service">The absolute URI to the service and object being called. </param>
		/// <param name="mediaType">The media type being requested.</param>
		/// <param name="tokenV1">A user authentication token which has been provided by the PWS Authentication Token Service.</param>
		/// <returns>A newly retrieved file within the standard Windows temporary directory,</returns>
		FileInfo GetBinaryFile(Uri service, string mediaType, PCRLE.Users.Token_V1 tokenV1);

		/// <summary>
		/// Post a binary file, e.g. a bitmap image, and get back an object representing the upload.
		/// </summary>
		/// <typeparam name="T">The type of object being received.</typeparam>
		/// <param name="service">The absolute URI to the service and object being called. </param>
		/// <param name="mediaType">The media type of the file being sent.</param>
		/// <param name="stream">The data stream being Posted.</param>
		/// <param name="tokenV1">A user authentication token which has been provided by the PWS Authentication Token Service.</param>
		/// <returns>Object of type T from service, e.g. Upload_V1.</returns>
		T PostBinaryFile<T>(Uri service, Stream stream, string mediaType, PCRLE.Users.Token_V1 tokenV1) where T : class;
	}
}
